package com.ld.onvif;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
@Slf4j
@Component
public class SendOnvifCmd {
	@Autowired
	private RestTemplate restTemplate;
	/**
	 * 存放token
	 */
	private Map<String,String> tokenMap = new HashMap<>();

	public String stream(String ip, int onvifPort , String onvifUsername, String onvifPassword ) {
		//获取token
		String token = this.getToken(ip, onvifPort,onvifUsername,onvifPassword);
		if(StringUtils.isEmpty(token))return "获取token失败！";
		//构造http请求头
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("text/xml;charset=UTF-8");
		headers.setContentType(type);
		HttpEntity<String> formEntity = new HttpEntity<String>(PackageXml.streamUri(onvifUsername,onvifPassword,token), headers);
		//返回结果
		String resultStr = restTemplate.postForObject("http://"+ ip +":"+ onvifPort +"/onvif/device_service", formEntity, String.class);
		//转换返回结果中的特殊字符，返回的结果中会将xml转义，此处需要反转移
		String xmlStr = StringEscapeUtils.unescapeXml(resultStr);
		log.debug( "stream返回：" + xmlStr);
		//JSONObject obj = XML.toJSONObject(tmpStr);
		String reg = "<tt:Uri>(.*?)\\</tt:Uri>";
        Pattern pattern = Pattern.compile(reg);
        // 内容 与 匹配规则 的测试
        Matcher matcher = pattern.matcher(xmlStr);
        if(matcher.find()){
            // 包含前后的两个字符 
            //System.out.println(matcher.group());
            // 不包含前后的两个字符
        	String rtspUrl = matcher.group(1).replace("rtsp://", "rtsp://"+ onvifUsername +":"+onvifPassword+"@");
            return rtspUrl;
        }else{
            //System.out.println(" 没有匹配到内容....");
			log.debug("没有获取到流地址");
        	return null;
        }
	}
	public String  ptz(String ip, int onvifPort , String onvifUsername, String onvifPassword ,Double leftRight,Double upDown,Double inOut) {

		//获取token
		String token = this.getToken(ip, onvifPort,onvifUsername,onvifPassword);
		if(StringUtils.isEmpty(token))return "获取token失败！";
		//构造http请求头
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("text/xml;charset=UTF-8");
		headers.setContentType(type);
		String xml = PackageXml.ptz(onvifUsername,onvifPassword,token,leftRight,upDown,inOut);
		HttpEntity<String> formEntity = new HttpEntity<String>(xml,headers);
		//返回结果
		String resultStr = restTemplate.postForObject("http://"+ ip +":"+ onvifPort +"/onvif/PTZ", formEntity, String.class);
		//转换返回结果中的特殊字符，返回的结果中会将xml转义，此处需要反转移
		String xmlStr = StringEscapeUtils.unescapeXml(resultStr);
		log.debug( "ptz返回：" + xmlStr);
		//JSONObject obj = XML.toJSONObject(tmpStr);
        return "";
	}

	public String  preset(String ip, int onvifPort , String onvifUsername, String onvifPassword ,String preset) {

		//获取token
		String token = this.getToken(ip, onvifPort,onvifUsername,onvifPassword);
		if(StringUtils.isEmpty(token))return "获取token失败！";
		//构造http请求头
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("text/xml;charset=UTF-8");
		headers.setContentType(type);
		String xml = PackageXml.preset(onvifUsername,onvifPassword,token,preset);
		HttpEntity<String> formEntity = new HttpEntity<String>(xml,headers);
		//返回结果
		String resultStr = restTemplate.postForObject("http://"+ ip +":"+ onvifPort +"/onvif/PTZ", formEntity, String.class);
		//转换返回结果中的特殊字符，返回的结果中会将xml转义，此处需要反转移
		String xmlStr = StringEscapeUtils.unescapeXml(resultStr);
		log.debug( "preset返回：" + xmlStr);
		//JSONObject obj = XML.toJSONObject(tmpStr);
		return "";
	}

	public String getToken(String ip, int onvifPort , String onvifUsername, String onvifPassword) {
		try {
			String token = tokenMap.get(ip);
			if(StringUtils.isEmpty(token)){
				// 构造http请求头
				HttpHeaders headers = new HttpHeaders();
				MediaType type = MediaType.parseMediaType("text/xml;charset=UTF-8");
				headers.setContentType(type);
				String tokenXml = PackageXml.token(onvifUsername, onvifPassword);
				HttpEntity<String> formEntity = new HttpEntity<String>(tokenXml, headers);
				// 返回结果
				String resultStr = restTemplate.postForObject("http://" + ip + ":" + onvifPort + "/onvif/Media", formEntity,String.class);
				//String resultStr = restTemplate.postForObject("http://" + rp.getIp() + ":" + rp.getOnvifPort() + "/onvif/device_service", formEntity,String.class);
				// 转换返回结果中的特殊字符，返回的结果中会将xml转义，此处需要反转移
				String xmlStr = StringEscapeUtils.unescapeXml(resultStr);
				SAXReader reader = new SAXReader();
				Document document = reader.read(new ByteArrayInputStream(xmlStr.getBytes("UTF-8")));
				Element root = document.getRootElement();
				token = root.element("Body").element("GetProfilesResponse").elements("Profiles").get(0).attribute("token").getText();
				tokenMap.put(ip,token);
				return token;
			}else{
				return token;
			}
		} catch (RestClientException | DocumentException | UnsupportedEncodingException e) {
			log.error(e.getMessage(),e);
			return null;
		} 
	}
}
